//////////////////////////////////////////////////////////////////////////
#pragma once
#pragma managed
//////////////////////////////////////////////////////////////////////////
using namespace System;
using namespace System::Runtime::InteropServices;
//////////////////////////////////////////////////////////////////////////
#include "CvStructs.h"
#include "CxTypes.Enums.h"
//////////////////////////////////////////////////////////////////////////
NAMESPACE_BEGIN
//////////////////////////////////////////////////////////////////////////
/// <summary>
/// Cv32suf
/// </summary>
[StructLayoutAttribute(LayoutKind::Explicit)]
value struct _32suf
{
	/// <summary>
	/// int
	/// </summary>
	[FieldOffsetAttribute(0)]
	int i;
	/// <summary>
	/// unsigned int
	/// </summary>
	[FieldOffsetAttribute(0)]
	unsigned int u;
	/// <summary>
	/// float
	/// </summary>
	[FieldOffsetAttribute(0)]
	float f;
};

/// <summary>
/// Cv64suf
/// </summary>
[StructLayoutAttribute(LayoutKind::Explicit)]
value struct _64suf
{
	/// <summary>
	/// long
	/// </summary>
	[FieldOffsetAttribute(0)]
	long long i;
	/// <summary>
	/// unsigned long
	/// </summary>
	[FieldOffsetAttribute(0)]
	unsigned long long u;
	/// <summary>
	/// double
	/// </summary>
	[FieldOffsetAttribute(0)]
	double f;
};

/// <summary>
/// CvRNG
/// </summary>
[StructLayoutAttribute(LayoutKind::Sequential)]
public value struct Rng
{
	/// <summary>
	/// Val: (OpenCV: typedef unsigned int64 CvRNG)
	/// </summary>
	UInt64 Val;
};

/// <summary>
/// Image
/// </summary>
[StructLayoutAttribute(LayoutKind::Sequential)]
public value struct Image
{
	/// <summary>
	/// sizeof(Image)
	/// </summary>
	int nSize;
	/// <summary>
	/// version (=0)
	/// </summary>
	int ID;
	/// <summary>
	/// Most of OpenCV functions support 1,2,3 or 4 channels
	/// </summary>
	int nChannels;
	/// <summary>
	/// Ignored by OpenCV
	/// </summary>
	int alphaChannel;
	/// <summary>
	/// Pixel depth in bits: IPL_DEPTH_8U, IPL_DEPTH_8S, IPL_DEPTH_16S,
	/// IPL_DEPTH_32S, IPL_DEPTH_32F and IPL_DEPTH_64F are supported.
	/// </summary>
	PixelDepth depth;
	/// <summary>
	/// Ignored by OpenCV
	/// </summary>
	inline_array<byte, 4> colorModel;
	/// <summary>
	/// ditto
	/// </summary>
	inline_array<byte, 4> channelSeq;
	/// <summary>
	/// 0 - interleaved color channels, 1 - separate color channels.
	/// cvCreateImage can only create interleaved images
	/// </summary>
	ImageDataOrder dataOrder;
	/// <summary>
	/// 0 - top-left origin,
	/// 1 - bottom-left origin (Windows bitmaps style).
	/// </summary>
	ImageOrigin origin;
	/// <summary>
	/// Alignment of image rows (4 or 8).
	/// OpenCV ignores it and uses widthStep instead.
	/// </summary>
	ImageAlign align;
	/// <summary>
	/// Image width in pixels.
	/// </summary>
	int width;
	/// <summary>
	/// Image height in pixels.
	/// </summary>
	int height;
	/// <summary>
	/// Image ROI. If NULL, the whole image is selected.
	/// </summary>
	IntPtr roi;
	/// <summary>
	/// Must be NULL.
	/// </summary>
	IntPtr maskROI;
	/// <summary>
	/// imageId
	/// </summary>
	IntPtr imageId;
	/// <summary>
	/// titleInfo
	/// </summary>
	IntPtr tileInfo;
	/// <summary>
	/// Image data size in bytes
	/// (==image->height*image->widthStep
	/// in case of interleaved data)
	/// </summary>
	int imageSize;
	/// <summary>
	/// Pointer to aligned image data.
	/// </summary>
	IntPtr imageData;
	/// <summary>
	/// Size of aligned image row in bytes.
	/// </summary>
	int widthStep;
	/// <summary>
	/// Ignored by OpenCV.
	/// </summary>
	inline_array<int, 4> BorderMode;
	/// <summary>
	/// Ditto.
	/// </summary>
	inline_array<int, 4> BorderConst;
	/// <summary>
	/// Pointer to very origin of image data
	/// (not necessarily aligned) -
	/// needed for correct deallocatio
	/// </summary>
	IntPtr imageDataOrigin;
};

/// <summary>
/// ImageROI
/// </summary>
[StructLayoutAttribute(LayoutKind::Sequential)]
public value struct ImageROI
{
private:
	/// <summary>
	/// 0 - no COI (all channels are selected), 1 - 0th channel is selected ...
	/// </summary>
	int coi;
	/// <summary>
	/// xOffset
	/// </summary>
	int xOffset;
	/// <summary>
	/// yOffset
	/// </summary>
	int yOffset;
	/// <summary>
	/// width
	/// </summary>
	int width;
	/// <summary>
	/// height
	/// </summary>
	int height;

public:
	/// <summary>
	/// 0 - no COI (all channels are selected), 1 - 0th channel is selected ...
	/// </summary>
	property int COI { int get() { return coi; } void set(int value) { coi = value; } };
	/// <summary>
	/// xOffset
	/// </summary>
	property int XOffset { int get() { return coi; } void set(int value) { coi = value; } };
	/// <summary>
	/// yOffset
	/// </summary>
	property int YOffset { int get() { return coi; } void set(int value) { coi = value; } };
	/// <summary>
	/// width
	/// </summary>
	property int Width { int get() { return coi; } void set(int value) { coi = value; } };
	/// <summary>
	/// height
	/// </summary>
	property int Height { int get() { return coi; } void set(int value) { coi = value; } };

	/// <summary>
	/// Convalue structor
	/// </summary>
	/// <param name="coi">coi</param>
	/// <param name="xOffset">xOffset</param>
	/// <param name="yOffset">yOffset</param>
	/// <param name="width">width</param>
	/// <param name="height">height</param>
	ImageROI(int coi, int xOffset, int yOffset, int width, int height)
	{
		this->coi = coi;
		this->xOffset = xOffset;
		this->yOffset = yOffset;
		this->width = width;
		this->height = height;
	};
};

/// <summary>
/// ImageConvKernel
/// </summary>
[StructLayoutAttribute(LayoutKind::Sequential)]
public value struct ImageConvKernel
{
	/// <summary>
	/// Cols
	/// </summary>
	int nCols;
	/// <summary>
	/// Rows
	/// </summary>
	int nRows;
	/// <summary>
	/// anchorX
	/// </summary>
	int anchorX;
	/// <summary>
	/// anchorY
	/// </summary>
	int anchorY;
	/// <summary>
	/// values
	/// </summary>
	IntPtr values;
	/// <summary>
	/// nShiftR
	/// </summary>
	int nShiftR;
};

/// <summary>
/// ImageConvKernelFP
/// </summary>
[StructLayoutAttribute(LayoutKind::Sequential)]
value struct ImageConvKernelFP
{
	/// <summary>
	/// Cols
	/// </summary>
	int nCols;
	/// <summary>
	/// nRows
	/// </summary>
	int nRows;
	/// <summary>
	/// anchorX
	/// </summary>
	int anchorX;
	/// <summary>
	/// anchorY
	/// </summary>
	int anchorY;
	/// <summary>
	/// values
	/// </summary>
	IntPtr values;
};

/// <summary>
/// CvMat
/// </summary>
[StructLayoutAttribute(LayoutKind::Sequential)]
public value struct Mat
{
	MatFlag type;
	/// <summary>
	/// for use only
	/// </summary>
	int step;
	IntPtr refcount;
	int hdr_refcount;
	IntPtr data;
	int rows;
	property int height { int get() { return rows; } void set(int value) { rows = value; } };
	int cols;
	property int width { int get() { return cols; } void set(int value) { cols = value; } };
};

/// <summary>
/// pairs (number of elements, distance between elements in bytes) for every dimension
/// </summary>
[StructLayoutAttribute(LayoutKind::Sequential, Size=(2*sizeof(int)))]
public value struct MatNDDim
{
	int size;
	int step;
};

/// <summary>
/// CvMatND
/// </summary>
[StructLayoutAttribute(LayoutKind::Sequential)]
public value struct MatND
{
	int type;
	int dims;
	IntPtr refcount;
	int hdr_refcount;
	IntPtr data;
	inline_array_ex<MatNDDim, 2*sizeof(int), CV_MAX_DIM> dim;
};

/// <summary>
/// CvSparseMat
/// </summary>
[StructLayoutAttribute(LayoutKind::Sequential)]
public value struct SparseMat
{
	int type;
	int dims;
	IntPtr refcount;
	int hdr_refcount;
	IntPtr heap;
	IntPtr hashtable;
	int hashsize;
	int valoffset;
	int idxoffset;
	inline_array<int, CV_MAX_DIM> size;
};

/// <summary>
/// iteration through a sparse array
/// </summary>
[StructLayoutAttribute(LayoutKind::Sequential)]
public value struct SparseNode
{
	unsigned int hashval;
	IntPtr next;
};

/// <summary>
/// CvSparseMatIterator
/// </summary>
[StructLayoutAttribute(LayoutKind::Sequential)]
public value struct SparseMatIterator
{
	IntPtr mat;
	IntPtr node;
	int curidx;
};

/// <summary>
/// CvRange32F
/// </summary>
[StructLayoutAttribute(LayoutKind::Sequential, Size=(2*sizeof(float)))]
public value struct Range32F
{
	float min;
	float max;
};

/// <summary>
/// CvHistogram
/// </summary>
[StructLayoutAttribute(LayoutKind::Sequential)]
public value struct Histogram
{
	HistType type;
	IntPtr bins;
	/// <summary>
	/// For uniform histograms.
	/// </summary>
	inline_array_ex<Range32F, 2*sizeof(float), CV_MAX_DIM> thresh;
	/// <summary>
	/// For non-uniform histograms.
	/// </summary>
	IntPtr thresh2;
	/// <summary>
	/// Embedded matrix header for array histograms
	/// </summary>
	MatND mat;
};

/// <summary>
/// offset and size of a rectangle
/// </summary>
[StructLayoutAttribute(LayoutKind::Sequential)]
public value struct Rect
{
private:
	/// <summary>
	/// x of the left-most rectangle corner[s]
	/// </summary>
	int x;

	/// <summary>
	/// y of the top-most or bottom-most rectangle corner[s]
	/// </summary>
	int y;

	/// <summary>
	/// width
	/// </summary>
	int width;

	/// <summary>
	/// height
	/// </summary>
	int height;

public:
	/// <summary>
	/// x of the left-most rectangle corner[s]
	/// </summary>
	property int X { int get() { return x; } void set(int value) { x = value; } };

	/// <summary>
	/// y of the top-most or bottom-most rectangle corner[s]
	/// </summary>
	property int Y { int get() { return y; } void set(int value) { y = value; } };

	/// <summary>
	/// width
	/// </summary>
	property int Width { int get() { return width; } void set(int value) { width = value; } };

	/// <summary>
	/// height
	/// </summary>
	property int Height { int get() { return height; } void set(int value) { height = value; } };

	/// <summary>
	/// Convalue structor
	/// </summary>
	/// <param name="x">x of the left-most rectangle corner[s]</param>
	/// <param name="y">y of the top-most or bottom-most rectangle corner[s]</param>
	/// <param name="width">width</param>
	/// <param name="height">height</param>
	Rect(int x, int y, int width, int height)
	{
		this->x = x;
		this->y = y;
		this->width = width;
		this->height = height;
	};
};

/// <summary>
/// Termination criteria for iterative algorithms
/// </summary>
[StructLayoutAttribute(LayoutKind::Sequential)]
public value struct TermCriteria
{
private:
	/// <summary>
	/// may be combination of
	/// CV_TERMCRIT_ITER 
	/// CV_TERMCRIT_EPS
	/// </summary>
	TermCriteriaType type;

	/// <summary>
	/// maximum number of iterations
	/// </summary>
	int maxIter;

	/// <summary>
	/// accuracy to achieve
	/// </summary>
	double epsilon;

public:
	/// <summary>
	/// may be combination of
	/// CV_TERMCRIT_ITER 
	/// CV_TERMCRIT_EPS
	/// </summary>
	property TermCriteriaType Type { TermCriteriaType get() { return type; } };

	/// <summary>
	/// maximum number of iterations
	/// </summary>
	property int MaxIter { int get() { return maxIter; } };

	/// <summary>
	/// accuracy to achieve
	/// </summary>
	property double Epsilon { double get() { return epsilon; } };

	/// <summary>
	/// Convalue structor
	/// check termination criteria and transform it so that type=CV_TERMCRIT_ITER+CV_TERMCRIT_EPS,
	/// and both max_iter and epsilon are valid
	/// </summary>
	/// <param name="type"> may be combination of
	/// CV_TERMCRIT_ITER 
	/// CV_TERMCRIT_EPS</param>
	/// <param name="max_iter">maximum number of iterations</param>
	/// <param name="epsilon">accuracy to achieve</param>
	TermCriteria(TermCriteriaType type, int max_iter, double epsilon)
	{
		this->type = type;
		this->maxIter = max_iter;
		this->epsilon = epsilon;
	};
};

/// <summary>
/// 2D point with integer coordinates
/// </summary>
[StructLayoutAttribute(LayoutKind::Sequential)]
public value struct Point2D32s
{
private: 
	/// <summary>
	/// x
	/// </summary>
	int x;

	/// <summary>
	/// y
	/// </summary>
	int y;

public:
	/// <summary>
	/// x
	/// </summary>
	property int X { int get() { return x; } void set(int value) { x = value; } };

	/// <summary>
	/// y
	/// </summary>
	property int Y { int get() { return y; } void set(int value) { y = value; } };

	/// <summary>
	/// convalue structor
	/// </summary>
	/// <param name="x">x</param>
	/// <param name="y">y</param>
	Point2D32s(int x, int y)
	{
		this->x = x;
		this->y = y;
	};
};

/// <summary>
/// 2D point with floating-point coordinates
/// </summary>
[StructLayoutAttribute(LayoutKind::Sequential)]
public value struct Point2D32f
{
private: 
	/// <summary>
	/// x
	/// </summary>
	float x;

	/// <summary>
	/// y
	/// </summary>
	float y;

public:
	/// <summary>
	/// x
	/// </summary>
	property float X { float get() { return x; } void set(float value) { x = value; } };

	/// <summary>
	/// y
	/// </summary>
	property float Y { float get() { return y; } void set(float value) { y = value; } };

	/// <summary>
	/// convalue structor
	/// </summary>
	/// <param name="x">x</param>
	/// <param name="y">y</param>
	Point2D32f(float x, float y)
	{
		this->x = x;
		this->y = y;
	};
};

/// <summary>
/// D point with floating-point coordinates
/// </summary>
[StructLayoutAttribute(LayoutKind::Sequential)]
public value struct Point3D32f
{
private:
	/// <summary>
	/// x
	/// </summary>
	float x;

	/// <summary>
	/// y
	/// </summary>
	float y;

	/// <summary>
	/// y
	/// </summary>
	float z;

public:
	/// <summary>
	/// x
	/// </summary>
	property float X { float get() { return x; } void set(float value) { x = value; } };

	/// <summary>
	/// y
	/// </summary>
	property float Y { float get() { return y; } void set(float value) { y = value; } };

	/// <summary>
	/// y
	/// </summary>
	property float Z { float get() { return z; } void set(float value) { z = value; } };

	/// <summary>
	/// Convalue structor
	/// </summary>
	/// <param name="x">x</param>
	/// <param name="y">y</param>
	/// <param name="z">z</param>
	Point3D32f(float x, float y, float z)
	{
		this->x = x;
		this->y = y;
		this->z = z;
	};
};

/// <summary>
/// 2D point with double precision floating-point coordinates
/// </summary>
[StructLayoutAttribute(LayoutKind::Sequential)]
public value struct Point2D64f
{
private: 
	/// <summary>
	/// x
	/// </summary>
	double x;

	/// <summary>
	/// y
	/// </summary>
	double y;

public:
	/// <summary>
	/// x
	/// </summary>
	property double X { double get() { return x; } void set(double value) { x = value; } };

	/// <summary>
	/// y
	/// </summary>
	property double Y { double get() { return y; } void set(double value) { y = value; } };

	/// <summary>
	/// Convalue structor
	/// </summary>
	/// <param name="x">x</param>
	/// <param name="y">y</param>
	Point2D64f(double x, double y)
	{
		this->x = x;
		this->y = y;
	};
};

/// <summary>
/// 3D point with double precision floating-point coordinates
/// </summary>
[StructLayoutAttribute(LayoutKind::Sequential)]
public value struct Point3D64f
{
private: 
	/// <summary>
	/// x
	/// </summary>
	double x;

	/// <summary>
	/// y
	/// </summary>
	double y;

	/// <summary>
	/// z
	/// </summary>
	double z;

public: 
	/// <summary>
	/// x
	/// </summary>
	property double X { double get() { return x; } void set(double value) { x = value; } };

	/// <summary>
	/// y
	/// </summary>
	property double Y { double get() { return y; } void set(double value) { y = value; } };

	/// <summary>
	/// z
	/// </summary>
	property double Z { double get() { return z; } void set(double value) { z = value; } };

	/// <summary>
	/// Convalue structor
	/// </summary>
	/// <param name="x">x</param>
	/// <param name="y">y</param>
	/// <param name="z">z</param>
	Point3D64f(double x, double y, double z)
	{
		this->x = x;
		this->y = y;
		this->z = z;
	};
};

/// <summary>
/// pixel accurate size of a rectangle
/// </summary>
[StructLayoutAttribute(LayoutKind::Sequential)]
public value struct Size2D32s
{
private: 
	/// <summary>
	/// width
	/// </summary>
	int width;
	/// <summary>
	/// height
	/// </summary>
	int height;

public: 
	/// <summary>
	/// width
	/// </summary>
	property int Width { int get() { return width; } void set(int value) { width = value; } };

	/// <summary>
	/// height
	/// </summary>
	property int Height { int get() { return height; } void set(int value) { height = value; } };

	/// <summary>
	/// Convalue structor
	/// </summary>
	/// <param name="width">width</param>
	/// <param name="height">height</param>
	Size2D32s(int width, int height)
	{
		this->width = width;
		this->height = height;
	};

	/// <summary>
	/// Empty
	/// </summary>
	static property Size2D32s Empty
	{
		Size2D32s get() { return Size2D32s(0, 0); }
	};
};

/// <summary>
/// sub-pixel accurate size of a rectangle
/// </summary>
[StructLayoutAttribute(LayoutKind::Sequential)]
public value struct Size2D32f
{
private:
	/// <summary>
	/// width
	/// </summary>
	float width;

	/// <summary>
	/// height
	/// </summary>
	float height;

public:
	/// <summary>
	/// width
	/// </summary>
	property float Width { float get() { return width; } void set(float value) { width = value; } };

	/// <summary>
	/// height
	/// </summary>
	property float Height { float get() { return height; } void set(float value) { height = value; } };


	/// <summary>
	/// Size Array
	/// </summary>
	/// <param name="width">width</param>
	/// <param name="height">height</param>
	Size2D32f(float width, float height)
	{
		this->width = width;
		this->height = height;
	};
};

/// <summary>
/// CvBox2D
/// </summary>
[StructLayoutAttribute(LayoutKind::Sequential)]
public value struct Box2D
{
private:
	/// <summary>
	/// center of the box
	/// </summary>
	Point2D32f center;

	/// <summary>
	/// box width and length
	/// </summary>
	Size2D32f size;

	/// <summary>
	/// angle between the horizontal axis
	/// and the first side (i.e. length) in degrees
	/// </summary>
	float angle;

public:
	/// <summary>
	/// center of the box
	/// </summary>
	property Point2D32f Center { Point2D32f get() { return center; } void set(Point2D32f value) { center = value; } };

	/// <summary>
	/// box width and length
	/// </summary>
	property Size2D32f Size { Size2D32f get() { return size; } void set(Size2D32f value) { size = value; } };

	/// <summary>
	/// angle between the horizontal axis
	/// and the first side (i.e. length) in degrees
	/// </summary>
	property float Angle { float get() { return angle; } void set(float value) { angle = value; } };

	/// <summary>
	/// Convalue structor
	/// </summary>
	/// <param name="center"></param>
	/// <param name="size"></param>
	/// <param name="angle"></param>
	Box2D(Point2D32f center, Size2D32f size, float angle)
	{
		this->center = center;
		this->size = size;
		this->angle = angle;
	};
};

/// <summary>
/// Line iterator state
/// </summary>
[StructLayoutAttribute(LayoutKind::Sequential)]
public value struct LineIterator
{
	/// <summary>
	/// pointer to the current point 
	/// </summary>
	IntPtr pt;

	/// <summary>
	/// Bresenham algorithm state
	/// </summary>
	int err;

	/// <summary>
	/// Bresenham algorithm state
	/// </summary>
	int plus_delta;

	/// <summary>
	/// Bresenham algorithm state
	/// </summary>
	int minus_delta;

	/// <summary>
	/// Bresenham algorithm state
	/// </summary>
	int plus_step;

	/// <summary>
	/// Bresenham algorithm state
	/// </summary>
	int minus_step;
};

/// <summary>
/// A sequence slice
/// </summary>
[StructLayoutAttribute(LayoutKind::Sequential)]
public value struct Slice
{
private:
	/// <summary>
	/// Start Index
	/// </summary>
	int start_index;

	/// <summary>
	/// End Index
	/// </summary>
	int end_index;

public:
	/// <summary>
	/// Start Index
	/// </summary>
	property int StartIndex { int get() { return start_index; } void set(int value) { start_index = value; } };

	/// <summary>
	/// End Index
	/// </summary>
	property int EndIndex { int get() { return end_index; } void set(int value) { end_index = value; } };

	/// <summary>
	/// Convalue structor
	/// </summary>
	/// <param name="start_index">Start Index</param>
	/// <param name="end_index">End Index</param>
	Slice(int start_index, int end_index)
	{
		this->start_index = start_index;
		this->end_index = end_index;
	};
};

/// <summary>
/// A container for 1-,2-,3- or 4-tuples of numbers
/// </summary>
[StructLayoutAttribute(LayoutKind::Sequential)]
public value struct Scalar
{
private:
	/// <summary>
	/// value 0
	/// </summary>
	inline_array<double, 4> vals;

public:
	/// <summary>
	/// value 0
	/// </summary>
	property double Val0 { double get() { return vals[0]; } void set(double value) { vals[0] = value; } };

	/// <summary>
	/// value 1
	/// </summary>
	property double Val1 { double get() { return vals[1]; } void set(double value) { vals[1] = value; } };

	/// <summary>
	/// value 2
	/// </summary>
	property double Val2 { double get() { return vals[2]; } void set(double value) { vals[2] = value; } };

	/// <summary>
	/// value 3
	/// </summary>
	property double Val3 { double get() { return vals[3]; } void set(double value) { vals[3] = value; } };

	/// <summary>
	/// Convalue structor
	/// </summary>
	/// <param name="v1">value 1</param>
	/// <param name="v2">value 2</param>
	/// <param name="v3">value 3</param>
	/// <param name="v4">value 4</param>
	Scalar(double v1, double v2, double v3, double v4)
	{
		vals[0] = v1; vals[1] = v2; vals[2] = v3; vals[3] = v4;
	}

	/// <summary>
	/// Convalue structor all values will void set(int value) to the input
	/// </summary>
	/// <param name="value">Input</param>
	Scalar(double v)
	{
		vals[0] = v; vals[1] = v; vals[2] = v; vals[3] = v;
	}

	/// <summary>
	/// Convalue structor, Input values are void set(int value), others becomes 0.
	/// </summary>
	/// <param name="v1">value 1</param>
	/// <param name="v2">value 2</param>
	Scalar(double v1, double v2)
	{
		vals[0] = v1; vals[1] = v2; vals[2] = 0; vals[3] = 0;
	}

	/// <summary>
	/// Convalue structor, Input values are void set(int value), others becomes 0.
	/// </summary>
	/// <param name="v1">value 1</param>
	/// <param name="v2">value 2</param>
	/// <param name="v3">value 3</param>
	Scalar(double v1, double v2, double v3)
	{
		vals[0] = v1; vals[1] = v2; vals[2] = v3; vals[3] = 0;
	}
};

/// <summary>
/// Memory storage
/// </summary>
[StructLayoutAttribute(LayoutKind::Sequential)]
public value struct MemBlock
{
	IntPtr prev;
	IntPtr next;
};

/// <summary>
/// CvMemStorage
/// </summary>
[StructLayoutAttribute(LayoutKind::Sequential)]
public value struct MemStorage
{
	int signature;
	/// <summary>
	/// First allocated block.
	/// </summary>
	IntPtr bottom;
	/// <summary>
	/// Current memory block - top of the stack.
	/// </summary>
	IntPtr top;
	/// <summary>
	/// We int get() new blocks from parent as needed.
	/// </summary>
	IntPtr parent;
	/// <summary>
	/// Block size.
	/// </summary>
	int block_size;
	/// <summary>
	/// Remaining free space in current block
	/// </summary>
	int free_space;
};

/// <summary>
/// CvMemStoragePos
/// </summary>
[StructLayoutAttribute(LayoutKind::Sequential)]
public value struct MemStoragePos
{
	IntPtr top;
	int free_space;
};

/// <summary>
/// Sequence
/// </summary>
[StructLayoutAttribute(LayoutKind::Sequential)]
public value struct SeqBlock
{
	/// <summary>
	/// Previous sequence block.
	/// </summary>
	IntPtr prev;
	/// <summary>
	/// Next sequence block.
	/// </summary>
	IntPtr next;
	/// <summary>
	/// Index of the first element in the block +
	/// </summary>
	int start_index;
	/// <summary>
	/// Number of elements in the block.
	/// </summary>
	int count;
	/// <summary>
	/// Pointer to the first element of the block
	/// </summary>
	IntPtr data;
};

/// <summary>
/// CvTreeNodeFields<TNodeType>
/// #define CV_TREE_NODE_FIELDS(node_type) 
/// </summary>
/// <typeparam name="TNodeType"></typeparam>
[StructLayoutAttribute(LayoutKind::Sequential)]
public value struct TreeNodeFields
{
	/// <summary>
	///  Miscellaneous flags.
	/// </summary>
	SeqFlag flags;
	/// <summary>
	/// Size of sequence header.
	/// </summary>
	int header_size;
	/// <summary>
	/// Previous sequence.
	/// </summary>
	IntPtr h_prev;
	/// <summary>
	/// Next sequence.
	/// </summary>
	IntPtr h_next;
	/// <summary>
	/// 2nd previous sequence.
	/// </summary>
	IntPtr v_prev;
	/// <summary>
	/// 2nd next sequence.
	/// </summary>
	IntPtr v_next;
};

/// <summary>
/// Elements can be dynamically inserted to or deleted from the sequence
/// </summary>
[StructLayoutAttribute(LayoutKind::Sequential)]
public value struct SequenceFields
{
	TreeNodeFields tree_node_fields;
	/// <summary>
	/// Total number of elements.
	/// </summary>
	int total;
	/// <summary>
	/// Size of sequence element in bytes.
	/// </summary>
	int elem_size;
	/// <summary>
	/// Maximal bound of the last block.
	/// </summary>
	IntPtr block_max;
	/// <summary>
	/// Current write pointer.
	/// </summary>
	IntPtr ptr;
	/// <summary>
	/// Grow seq this many at a time.
	/// </summary>
	int delta_elems;
	/// <summary>
	/// Where the seq is stored.
	/// </summary>
	IntPtr storage;
	/// <summary>
	/// Free blocks list.
	/// </summary>
	IntPtr free_blocks;
	/// <summary>
	/// Pointer to the first sequence block.
	/// </summary>
	IntPtr first;
};

/// <summary>
/// CvSeq
/// </summary>
[StructLayoutAttribute(LayoutKind::Sequential)]
public value struct Seq
{
	/// <summary>
	/// fields
	/// </summary>
	SequenceFields fields;
};

/// <summary>
/// CvSetElem
/// </summary>
[StructLayoutAttribute(LayoutKind::Sequential)]
public value struct SetElemFields
{
	/// <summary>
	///  Miscellaneous flags.
	/// </summary>
	SeqFlag flags;
	/// <summary>
	/// Next node
	/// </summary>
	IntPtr next_free;
};

/// <summary>
/// CvSetElem
/// </summary>
[StructLayoutAttribute(LayoutKind::Sequential)]
public value struct SetElem
{
	/// <summary>
	/// fields
	/// </summary>
	SetElemFields fields;
};

/// <summary>
/// CvSetElem
/// </summary>
[StructLayoutAttribute(LayoutKind::Sequential)]
public value struct SetFields
{
	/// <summary>
	/// sequence_fields
	/// </summary>
	SequenceFields sequence_fields;
	/// <summary>
	/// free_elems
	/// </summary>
	IntPtr free_elems;
	/// <summary>
	/// active count
	/// </summary>
	int active_count;
};

/// <summary>
///  Set.
///  Order is not preserved. There can be gaps between sequence elements.
///  After the element has been inserted it stays in the same place all the time.
///  The MSB(most-significant or sign bit) of the first field (flags) is 0 iff the element exists.
/// </summary>
[StructLayoutAttribute(LayoutKind::Sequential)]
public value struct Set
{
	/// <summary>
	/// fields
	/// </summary>
	SetFields fields;
};

/// <summary>
/// CvGraphEdgeFields
/// </summary>
[StructLayoutAttribute(LayoutKind::Sequential)]
public value struct GraphEdgeFields
{
	SeqFlag flags;
	float weight;
	inline_array_ex<IntPtr, sizeof(size_t), 2> next;
	inline_array_ex<IntPtr, sizeof(size_t), 2> vtx;
};

/// <summary>
/// CvGraphVertexFields
/// </summary>
[StructLayoutAttribute(LayoutKind::Sequential)]
public value struct GraphVertexFields
{
	/// <summary>
	/// flags
	/// </summary>
	SeqFlag flags;
	/// <summary>
	/// first
	/// </summary>
	IntPtr first;
};

/// <summary>
/// CvGraphEdge
/// </summary>
[StructLayoutAttribute(LayoutKind::Sequential)]
public value struct GraphEdge
{
	/// <summary>
	/// fields
	/// </summary>
	GraphEdgeFields fields;
};

[StructLayoutAttribute(LayoutKind::Sequential)]
public value struct GraphVtx
{
	/// <summary>
	/// fields
	/// </summary>
	GraphVertexFields fields;
};

[StructLayoutAttribute(LayoutKind::Sequential)]
public value struct GraphVtx2D
{
	/// <summary>
	/// fields
	/// </summary>
	GraphVertexFields fields;
	/// <summary>
	/// point pointer
	/// </summary>
	IntPtr ptr;
};

/// <summary>
/// CvGraphVertexFields
/// </summary>
[StructLayoutAttribute(LayoutKind::Sequential)]
public value struct GraphFields
{
	/// <summary>
	/// fields
	/// </summary>
	SetFields set_fields;
	/// <summary>
	/// edges
	/// </summary>
	IntPtr edges;
};

/// <summary>
///   We represent a graph as a void set(int value) of vertices.
/// Vertices contain their adjacency lists (more exactly, pointers to first incoming or
/// outcoming edge (or 0 if isolated vertex)). Edges are stored in another void set(int value).
/// There is a singly-linked list of incoming/outcoming edges for each vertex.
/// Each edge consists of
///   o   Two pointers to the starting and ending vertices
///       (vtx[0] and vtx[1] respectively).
///   A graph may be oriented or not. In the latter case, edges between
///   vertex i to vertex j are not distinguished during search operations.
///   o   Two pointers to next edges for the starting and ending vertices, where
///       next[0] points to the next edge in the vtx[0] adjacency list and
///       next[1] points to the next edge in the vtx[1] adjacency list.
/// </summary>
[StructLayoutAttribute(LayoutKind::Sequential)]
public value struct Graph
{
	/// <summary>
	/// fields
	/// </summary>
	GraphFields fields;
};

/// <summary>
/// CvChain
/// </summary>
[StructLayoutAttribute(LayoutKind::Sequential)]
public value struct Chain
{
	/// <summary>
	/// fields
	/// </summary>
	SequenceFields fields;
	/// <summary>
	/// Origin
	/// </summary>
	Point2D32s origin;
};

/// <summary>
/// CvContourFields
/// </summary>
[StructLayoutAttribute(LayoutKind::Sequential)]
public value struct ContourFields
{
	/// <summary>
	/// fields
	/// </summary>
	SequenceFields sequence_fields;
	/// <summary>
	/// Region
	/// </summary>
	Rect rect;
	/// <summary>
	/// Color
	/// </summary>
	int color;
	/// <summary>
	/// Reserved
	/// </summary>
	inline_array<int, 3> reserved;
};

/// <summary>
/// CvContour
/// </summary>
[StructLayoutAttribute(LayoutKind::Sequential)]
public value struct Contour
{
	/// <summary>
	/// fields
	/// </summary>
	ContourFields fields;
};

/// <summary>
/// CvPoint2DSeq
/// </summary>
[StructLayoutAttribute(LayoutKind::Sequential)]
public value struct Point2DSeq
{
	/// <summary>
	/// fields
	/// </summary>
	ContourFields fields;
};

/// <summary>
/// CvSeqWriterFields
/// </summary>
[StructLayoutAttribute(LayoutKind::Sequential)]
public value struct SeqWriterFields
{
	/// <summary>
	/// header size
	/// </summary>
	int header_size;
	/// <summary>
	/// sequence, beign read
	/// </summary>
	IntPtr seq;
	/// <summary>
	/// current block
	/// </summary>
	IntPtr block;
	/// <summary>
	/// pointer to element be read next 
	/// </summary>
	IntPtr ptr;
	/// <summary>
	///  pointer to the beginning of block 
	/// </summary>
	IntPtr block_min;
	/// <summary>
	/// pointer to the end of block
	/// </summary>
	IntPtr block_max;
};


/// <summary>
/// CvSeqWriter
/// </summary>
[StructLayoutAttribute(LayoutKind::Sequential)]
public value struct SeqWriter
{
	/// <summary>
	/// Fields
	/// </summary>
	SeqWriterFields fields;
};

/// <summary>
/// CvSeqReaderFields
/// </summary>
[StructLayoutAttribute(LayoutKind::Sequential)]
public value struct SeqReaderFields
{
	/// <summary>
	/// header size
	/// </summary>
	int header_size;
	/// <summary>
	/// sequence, beign read
	/// </summary>
	IntPtr seq;
	/// <summary>
	/// current block
	/// </summary>
	IntPtr block;
	/// <summary>
	/// pointer to element be read next 
	/// </summary>
	IntPtr ptr;
	/// <summary>
	///  pointer to the beginning of block 
	/// </summary>
	IntPtr block_min;
	/// <summary>
	/// pointer to the end of block
	/// </summary>
	IntPtr block_max;
	/// <summary>
	/// = seq->first->start_index 
	/// </summary>
	int delta_index;
	/// <summary>
	/// pointer to previous element
	/// </summary>
	IntPtr prev_elem;
};

/// <summary>
/// CvSeqReader
/// </summary>
[StructLayoutAttribute(LayoutKind::Sequential)]
public value struct SeqReader
{
	/// <summary>
	/// fields
	/// </summary>
	SeqReaderFields fields;
};

/// <summary>
/// List of attributes
/// </summary>
[StructLayoutAttribute(LayoutKind::Sequential)]
public value struct AttrList
{
	/// <summary>
	/// NULL-terminated array of (attribute_name,attribute_value) pairs.
	/// </summary>
	IntPtr attr;
	/// <summary>
	/// Pointer to next chunk of the attributes list.
	/// </summary>
	IntPtr next;
};

/// <summary>
/// CvString
/// </summary>
[StructLayoutAttribute(LayoutKind::Sequential)]
public value struct String
{
	int len;
	IntPtr ptr;
};

/// <summary>
/// CvStringHashNode
/// All the keys (names) of elements in the readed file storage
/// are stored in the hash to speed up the lookup operations:
/// </summary>
[StructLayoutAttribute(LayoutKind::Sequential)]
public value struct StringHashNode
{
	unsigned int hashval;
	String str;
	IntPtr next;
};

/// <summary>
/// CvFileNodeData
/// </summary>
[StructLayoutAttribute(LayoutKind::Explicit)]
public value struct FileNodeData
{
	/// <summary>
	/// scalar floating-point number
	/// </summary>
	[FieldOffsetAttribute(0)]
	double f;
	/// <summary>
	/// scalar integer number
	/// </summary>
	[FieldOffsetAttribute(0)]
	int i;
	/// <summary>
	/// text String^
	/// </summary>
	[FieldOffsetAttribute(0)]
	String str;
	/// <summary>
	/// sequence (ordered collection of file nodes)
	/// </summary>
	[FieldOffsetAttribute(0)]
	IntPtr seq_ptr;
	/// <summary>
	/// map (collection of named file nodes)
	/// </summary>
	[FieldOffsetAttribute(0)]
	IntPtr map_ptr;
};

/// <summary>
/// Basic element of the file storage - scalar or collection
/// </summary>
[StructLayoutAttribute(LayoutKind::Sequential)]
public value struct FileNode
{
	/// <summary>
	/// Tag
	/// </summary>
	FileNodeFlag tag;
	/// <summary>
	/// type information
	/// </summary>
	IntPtr info;

	/// <summary>
	/// Data
	/// </summary>
	FileNodeData data;
};

/// <summary>
/// CvIsInstanceFunc
/// </summary>
/// <param name="value struct_ptr"></param>
/// <returns></returns>
[UnmanagedFunctionPointerAttribute(CallingConvention::Cdecl)]
public delegate int IsInstanceFunc(IntPtr struct_ptr);
/// <summary>
/// CvReleaseFunc
/// </summary>
/// <param name="value struct_dblptr"></param>
[UnmanagedFunctionPointerAttribute(CallingConvention::Cdecl)]
public delegate void ReleaseFunc(IntPtr& struct_dblptr);
/// <summary>
/// CvReadFunc
/// </summary>
/// <param name="storage"></param>
/// <param name="node"></param>
/// <returns></returns>
[UnmanagedFunctionPointerAttribute(CallingConvention::Cdecl)]
public delegate IntPtr ReadFunc(IntPtr storage, FileNode& node);
/// <summary>
/// CvWriteFunc
/// </summary>
/// <param name="storage"></param>
/// <param name="name"></param>
/// <param name="value struct_ptr"></param>
/// <param name="attributes"></param>
[UnmanagedFunctionPointerAttribute(CallingConvention::Cdecl)]
public delegate void WriteFunc(IntPtr storage, [MarshalAsAttribute(UnmanagedType::LPStr)]String^ name, IntPtr struct_ptr, AttrList attributes);
/// <summary>
/// CvCloneFunc
/// </summary>
/// <param name="value struct_ptr"></param>
/// <returns></returns>
[UnmanagedFunctionPointerAttribute(CallingConvention::Cdecl)]
public delegate IntPtr CloneFunc(IntPtr struct_ptr);

/// <summary>
/// CvTypeInfo
/// </summary>
[StructLayoutAttribute(LayoutKind::Sequential)]
public value struct TypeInfo
{
	int flags;
	int header_size;
	IntPtr prev;
	IntPtr next;
	IntPtr type_name;
	[MarshalAsAttribute(UnmanagedType::FunctionPtr)]
	IsInstanceFunc^ is_instance;
	[MarshalAsAttribute(UnmanagedType::FunctionPtr)]
	ReleaseFunc^ release;
	[MarshalAsAttribute(UnmanagedType::FunctionPtr)]
	ReadFunc^ read;
	[MarshalAsAttribute(UnmanagedType::FunctionPtr)]
	WriteFunc^ write;
	[MarshalAsAttribute(UnmanagedType::FunctionPtr)]
	CloneFunc^ clone;
};

/// <summary>
/// CvPluginFuncInfo
/// </summary>
[StructLayoutAttribute(LayoutKind::Sequential)]
public value struct PluginFuncInfo
{
	IntPtr func_addr;
	IntPtr default_func_addr;
	[MarshalAsAttribute(UnmanagedType::LPStr)]
	String^ func_names;
	int search_modules;
	int loaded_from;
};

/// <summary>
/// CvModuleInfo
/// </summary>
[StructLayoutAttribute(LayoutKind::Sequential)]
public value struct ModuleInfo
{
	IntPtr next;
	[MarshalAsAttribute(UnmanagedType::LPStr)]
	String^ name;
	[MarshalAsAttribute(UnmanagedType::LPStr)]
	String^ version;
	IntPtr func_tab;
};
//////////////////////////////////////////////////////////////////////////
NAMESPACE_END
//////////////////////////////////////////////////////////////////////////